package com.yxt.dispatch.aspect;

import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.yxt.common.exception.BizCodeEnume;
import com.yxt.common.exception.UnauthorizedException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

//@Slf4j
//@Aspect
//@Component
//@Order(1)
public class AuthrizationAspect {

    @Value("#{'${whiteList}'.split(',')}")
    private String[] whiteList;

    @Around("execution(* com.yxt..*Controller.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object proceed = null;
        //System.out.println("permitPath"+permitPath);

                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String requestPath = request.getServletPath();
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
                PathMatcher matcher = new AntPathMatcher();
                AtomicReference<Boolean> hasAuthority= new AtomicReference<>(false);

                AtomicBoolean permit= new AtomicBoolean(false);
                if(whiteList!=null){
                    Arrays.asList(whiteList).forEach(item->{
                        if(matcher.match(item,requestPath)){
                            permit.set(true);
                        }
                    });
                }
                List<String> permitPaths = Arrays.asList(whiteList);
                System.out.println("permitPaths: "+permitPaths);
                System.out.println("requestPath: "+requestPath);
                System.out.println("permit.get: "+permit.get());
                System.out.println("authorities: "+authorities);
                if(!permit.get()){
                    authorities.forEach(item->{
                        if(matcher.match(requestPath,item.toString())){
                            hasAuthority.set(true);
                        }
                    });
                    if(!hasAuthority.get()){
                        throw new UnauthorizedException(BizCodeEnume.UNAUTHORIZED_EXCEPTION);
                        //return Resp.fail("无权限访问");
                    }
                }
            proceed = point.proceed(point.getArgs());

        return proceed;
    }

}
